/**
 * @ProjectName: 
 * @Copyright: 2014 lisheng. All Right Reserved.
 * @address: toughheart@163.com
 * @date: 2015年10月12日 下午8:20:17
 * @Description: 本内容未经本人允许禁止使用、转发.
 */

package com.ls.fw.web.file.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.ls.fw.commons.core.utils.file.FileUtil;
import com.ls.fw.data.bean.ResultStatus;
import com.ls.fw.data.bean.ResultTemplate;
import com.ls.fw.mvc.springmvc.support.annotation.PathVariables;
import com.ls.fw.web.core.servlet.utils.HttpUtils;
import com.ls.fw.web.file.bean.FileErrorInfo;
import com.ls.fw.web.file.bean.FileInfo;
import com.ls.fw.web.file.support.config.IFileConfiguration;
import com.ls.fw.web.file.support.exception.FileInValidException;
import com.ls.fw.web.file.utils.FileUtils;

/**
 * 文件控制器 初始化参数： 根目录："baseDir"; 是否为绝对路径："isAbsolutePath"; 文件临时路径："tempdir";
 * 单个最大文件大小："maxFileSize"; 最大内存大小："maxMemSize"; 允许上传的类型（多个用“,”分割）："allowType";
 * 不允许上传的类型（多个用“,”分割）："denyType";
 * 
 * @author lisheng
 * @date 2015年10月12日 下午8:20:17
 * @version V1.0
 */
@Controller
@RequestMapping(value = "/file")
public class FileController extends BaseFileController implements InitializingBean,
ServletContextAware {

	
	
	@Autowired
	private IFileConfiguration fileConfiguration = null;
	
	
	
	@RequestMapping(value = "/" + DOWNLOAD + "1" + "/**")
	public Object downloads(HttpServletRequest request,
			@PathVariables(value = "path") String path, String name,
			HttpServletResponse response) throws IOException {
		
		String f = fileConfiguration.getBaseDir() + File.separator + path;
		String savename = name;
		if (StringUtils.isBlank(savename)) {
			savename = FileUtil.getFileName(path);
		}
		InputStream inputStream = new FileInputStream(new File(f));
		HttpUtils.encode(request, response, savename);
		down(inputStream, response);
		return null;
	}

	/**
	 * 下载文件
	 */
	@RequestMapping(value = "" + IFileConfiguration.DEFAULT_DOWNLOAD_BASE_URL + "/**")
	public ResponseEntity<byte[]> downloads(HttpServletRequest request,
			@PathVariables(value = "path") String path, String name)
			throws IOException {
		
		String savename = name;
		if (StringUtils.isBlank(savename)) {
			savename = FileUtil.getFileName(path);
		}
		String f = FileUtil.toLocalSeparator(fileConfiguration.getBaseDir() + File.separator + path);
		File f1 = new File(f);
		if (!f1.exists()) {
			this.logger.error("文件" + f1.getPath() + "不存在！");
			throw new FileInValidException(ResultStatus.BAD_REQUEST,"文件【" + path + "】不存在！");
		}
		FileInputStream is = new FileInputStream(f1);
		return super.download(request, savename, is);
	}

	@RequestMapping("/" + UPLOAD)
	public ModelAndView upload(DefaultMultipartHttpServletRequest request,
			HttpServletResponse response, WebRequest webRequest)
			throws Exception {
		return this.doUpload(request, webRequest, "", new UploadWorkHandler() {

			@Override
			public ResultTemplate doWork(DefaultMultipartHttpServletRequest request,
					WebRequest webRequest) throws Exception {
				final ResultTemplate obj = ResultTemplate.newInstance();
				try {
					final Map<String, Object> map = new HashMap<String, Object>();
					final List<FileErrorInfo> fail = new ArrayList<FileErrorInfo>();
					final List<FileInfo> success = new ArrayList<FileInfo>();
					uploadHandler(request, new FileUploadHandler() {

						@Override
						public FileInfo save(String fileFieldName,String saveDir,String saveName,
								MultipartFile file, HttpServletRequest request)
								throws Exception {
							FileInfo fileInfo = null;
							String downloadBaseUrl = fileConfiguration.getBaseUrl(
									request);
							fileInfo = saveFile(request, file, saveDir,saveName, downloadBaseUrl);

							return fileInfo;
						}

						@Override
						public void fail(Exception e, String fileFieldName,String saveDir,String saveName,
								MultipartFile file, HttpServletRequest request)
								throws Exception {
							FileErrorInfo info = new FileErrorInfo();
							info.setFileName(file.getOriginalFilename());
							info.setFieldName(fileFieldName);
							info.setMsg(e.getMessage());
							fail.add(info);
						}

						@Override
						public void success(FileInfo fileInfo,
								String fileFieldName,String saveDir,String saveName, MultipartFile file,
								HttpServletRequest request) throws Exception {
							success.add(fileInfo);
						}

						@Override
						public void check(IFileConfiguration fileConfiguration,
								MultipartFile file, HttpServletRequest request,String saveDir,String saveName)
								throws Exception {
							if (!FileUtils.checkFileName(saveName)) {
								throw new FileInValidException(ResultStatus.BAD_REQUEST,"文件名【" + saveName + "】不合法！");
							}
							isValid(fileConfiguration, file, request);
						}

					});
					map.put("fail", fail);
					map.put("success", success);
					obj.setData(map);
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}

	@Override
	public void setServletContext(ServletContext servletContext) {
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		RequestMapping requestMapping = this.getClass().getAnnotation(
				RequestMapping.class);
		final String pathString = requestMapping.value()[0] + IFileConfiguration.DEFAULT_DOWNLOAD_BASE_URL;
		fileConfiguration.setDownloadFunPath(pathString);
	}
	
	@Override
	public IFileConfiguration getFileConfiguration() {
		return fileConfiguration;
	}

	@Override
	protected String getFileDownloadBaseRequestMappingValue() {
		return IFileConfiguration.DEFAULT_DOWNLOAD_BASE_URL;
	}
}
